#include "EpollSvr.hpp"

#define CHECK_RET(ret)\
  if(ret < 0){\
    return 0;\
  }
  
int main(int argc, char* argv[]){
  if(argc < 3){
    printf("[ip]: [port]\n");
    return 0;
  }
  std::string ip(argv[1]);
  uint16_t port = atoi(argv[2]);
  TcpSocket svr_tcp;

  sockaddr_in svr_addr;
  svr_addr.sin_family = AF_INET;
  svr_addr.sin_port = htons(port);
  inet_aton(argv[1], &svr_addr.sin_addr);

  CHECK_RET(svr_tcp.CreateSocket());
  CHECK_RET(svr_tcp.Bind(svr_addr));
  CHECK_RET(svr_tcp.Listen());

  EpollSvr e_svr;
  CHECK_RET(e_svr.AddFd(svr_tcp.GetFd(), svr_addr));

  while(1){
    std::vector<std::pair<TcpSocket, sockaddr_in>> sockets;
    int ret = e_svr.EpollWait(sockets, 850);
    if(ret < 0){
      perror("epoll_wait");
      continue;
    }
    if(ret == 0){
      printf("epoll timeout\n");
      continue;
    }
    for(auto e : sockets){
      if(e.first.GetFd() == svr_tcp.GetFd()){
        TcpSocket cli;
        sockaddr_in cli_addr;
        svr_tcp.Accept(cli, cli_addr);
        printf("Have a new connect: [ip:%s] [port:%d]\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
        e_svr.AddFd(cli.GetFd(), cli_addr);
      }
      else{
        std::string buf;
        int ret = e.first.Recv(buf);
        if(ret > 0){
          printf("TcpEpoll:[%d]", e.first.GetFd());
          printf("Client say:\"%s\"\n", buf.data());
        }
        else if(ret <= 0){
          printf("Connection: [%s] [%d] disconnect\n", inet_ntoa(e.second.sin_addr), ntohs(e.second.sin_port));
          e_svr.DelFd(e.first.GetFd());
          e.first.Close();
        }
      }
    }
  }

  return 0;
}
